
///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2009, Perry L Miller IV
//  All rights reserved.
//  BSD License: http://www.opensource.org/licenses/bsd-license.html
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//
//  Recursive mutex class for Windows.
//  http://msdn.microsoft.com/en-us/library/ms682530.aspx
//
///////////////////////////////////////////////////////////////////////////////

#include "Usul/Threads/WindowsMutex.h"

#include <stdexcept>

#ifdef __GNUC__
# include <errno.h>
#endif

using namespace Usul::Threads;


///////////////////////////////////////////////////////////////////////////////
//
//  Constructor.
//
///////////////////////////////////////////////////////////////////////////////

WindowsMutex::WindowsMutex() : _cs()
{
  ::InitializeCriticalSection( &_cs );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Destructor.
//
///////////////////////////////////////////////////////////////////////////////

WindowsMutex::~WindowsMutex()
{
  ::DeleteCriticalSection( &_cs );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Lock the mutex.
//
///////////////////////////////////////////////////////////////////////////////

void WindowsMutex::lock()
{
  ::EnterCriticalSection ( &_cs );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Unlock the mutex.
//
///////////////////////////////////////////////////////////////////////////////

void WindowsMutex::unlock()
{
  ::LeaveCriticalSection ( &_cs );
}


///////////////////////////////////////////////////////////////////////////////
//
//  Try to lock the mutex.  Will return true if the lock has been acquired.
//
///////////////////////////////////////////////////////////////////////////////

bool WindowsMutex::trylock()
{
  return ( 0 != ::TryEnterCriticalSection ( &_cs ) );
}
